package com.sunda.spmsoversea.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.sunda.spmscommon.ResponseResult;
import com.sunda.spmscommon.feign.IFeignServiceCommon;
import com.sunda.spmsoversea.dto.OverseaConsumptionDTO;
import com.sunda.spmsoversea.dto.OverseaReport;
import com.sunda.spmsoversea.dto.WelcomePageSearchDTO;
import com.sunda.spmsoversea.dto.WelcomePageWerksOrderDTO;
import com.sunda.spmsoversea.mapper.OverseaReportMapper;
import com.sunda.spmsoversea.service.IOverseaReportService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;

/**
 * @program: spms
 * @description:
 * @author: Wayne Wu
 * @create: 2022-01-11 09:55
 **/
@Service
@Slf4j
public class OverseaReportServiceImpl implements IOverseaReportService {

    @Autowired
    OverseaReportMapper overseaReportMapper;

    @Autowired
    IFeignServiceCommon iFeignServiceCommon;

    /** 库龄分析报表计算逻辑步骤：
     1.按指定条件查询工厂仓库库存，工厂字段必输，查询结果不带储位，按料号数量求和；
     2.遍历物料仓库库存，按工厂、仓库、料号，查询物料库存增加记录日志，按天汇总每天增加数量；
     */
    @Override
    public List<Map<String, Object>> getInventoryAge(String werks, String whsLocationCode, String materialNo, Integer daysSearch) {
        daysSearch = daysSearch == null ? 0 : daysSearch;
        List<Map<String, Object>> inventoryAgeList = new ArrayList<>();
        List<Map<String, Object>> whsInventory = overseaReportMapper.getWhsInventory(werks, whsLocationCode, materialNo);
        int item = 1;
        if (whsInventory != null && whsInventory.size() > 0){
            for (int i = 0; i < whsInventory.size(); i++){
                werks = whsInventory.get(i).get("werks").toString();
                whsLocationCode = whsInventory.get(i).get("whsLocationCode").toString();
                materialNo = whsInventory.get(i).get("materialNo").toString();
                double totalQuantity = Double.parseDouble(whsInventory.get(i).get("quantity").toString());
                String materialZhDesc = whsInventory.get(i).get("materialZhDesc").toString();
                String materialEnDesc = whsInventory.get(i).get("materialEnDesc").toString();
                String basicUnit = whsInventory.get(i).get("basicUnit").toString();

                List<Map<String, Object>> whsOperateLogList = overseaReportMapper.getWhsOperate(werks, whsLocationCode, materialNo);
                if (whsOperateLogList != null && whsOperateLogList.size() > 0){
                    double tempQuantity = totalQuantity;
                    for (int j = 0; j < whsOperateLogList.size(); j ++){
                        Map<String, Object> inventoryAge = new HashMap<>();
                        double quantity = Double.parseDouble(whsOperateLogList.get(j).get("quantity").toString());
                        String createDate = whsOperateLogList.get(j).get("createDate").toString();
                        Integer days = Integer.parseInt(whsOperateLogList.get(j).get("days").toString());
                        tempQuantity = tempQuantity - quantity;
                        inventoryAge.put("rowId", item);
                        item ++;
                        inventoryAge.put("werks", werks);
                        inventoryAge.put("whsLocationCode", whsLocationCode);
                        inventoryAge.put("materialNo", materialNo);
                        inventoryAge.put("createDate", createDate);
                        inventoryAge.put("days", days);
                        inventoryAge.put("materialZhDesc", materialZhDesc);
                        inventoryAge.put("materialEnDesc", materialEnDesc);
                        inventoryAge.put("basicUnit", basicUnit);
                        if (tempQuantity <= 0){
                            inventoryAge.put("quantity", (tempQuantity + quantity));
                            inventoryAgeList.add(inventoryAge);
                            break;
                        }
                        inventoryAge.put("quantity", quantity);
                        inventoryAgeList.add(inventoryAge);
                    }
                }
            }
        }
        if (daysSearch <= 0 || inventoryAgeList.size() == 0){
            return inventoryAgeList;
        }
        List<Map<String, Object>> searchResult = new ArrayList<>();
        for (int k = 0; k < inventoryAgeList.size(); k ++){
            Map<String, Object> inventoryAge = inventoryAgeList.get(k);
            if (Integer.parseInt(inventoryAge.get("days").toString()) >= daysSearch){
                searchResult.add(inventoryAge);
            }
        }
        return searchResult;
    }

    /** 库龄分析(按箱码) */
    @Override
    public List<Map<String, Object>> getBoxInventoryAge(String werks, String whsLocationCode, String boxNote, Integer days) {
        days = days == null ? 0 : days;
        return overseaReportMapper.getBoxInventoryAge(werks, whsLocationCode, boxNote, days);
    }

    /** 获取耗用记录 */
    @Override
    public List<Map<String, Object>> getConsumptionRecord(OverseaConsumptionDTO dto) {
        return overseaReportMapper.getConsumptionRecord(dto);
    }

    /**
     机电主任登录首页信息统计，首页待办项信息展示：
     1.(机电主任)需求提报单审批：获取当前人关联工厂下待审批的车间请购单数量；跨工厂合并，全周期；
     2.(机电主任)工厂请购单：获取本人创建的待提交/待重提SRM/OA审批不通过的工厂请购单数量；跨工厂合并，全周期；
                 各状态单据量；跨工厂合并、近30天；
     3.非目录物料申请单：待提交——获取本人创建的非目录物料申请待提交OA的数量；跨工厂合并，全周期；
                      编码未发放——获取本人创建的非目录物料申请，编码为空的明细行数；跨工厂合并，全周期；
     4.车间领用单：待审批——获取当前人关联工厂待审批的领用单；跨工厂合并，全周期；
                 待领用——获取本人创建的审批通过但未生成出库任务的领用任务；跨工厂合并，全周期；
     5.(车间主任)需求提报单审批：获取本人创建的需求申请单，待提交 和 审批不通过、已提交三个状态下数量，本人关联工厂内数据；跨工厂合并，全周期；
      */
    @Override
    public List<Map<String, Object>> getToDoTasks(String userId) {
        List<Map<String, Object>> toDoTaskList = new ArrayList<>();
        Map<String, Object> orderWorkshopToDoItemsMap = new HashMap<>();
        orderWorkshopToDoItemsMap.put("orderWorkshopToDoItems", overseaReportMapper.orderWorkshopToDoItemsMap(userId));
        toDoTaskList.add(orderWorkshopToDoItemsMap);

        Map<String, Object> orderWerksToDoItemsMap = new HashMap<>();
        orderWerksToDoItemsMap.put("orderWerksToDoItems", overseaReportMapper.orderWerksToDoItemsMap(userId));
        toDoTaskList.add(orderWerksToDoItemsMap);

        Map<String, Object> orderWerksQuantityEachStatus = new HashMap<>();
        orderWerksQuantityEachStatus.put("orderWerksQuantityEachStatus", overseaReportMapper.orderWerksQuantityEachStatus(userId));
        toDoTaskList.add(orderWerksQuantityEachStatus);

        Map<String, Object> materialApplicationToDoItems = new HashMap<>();
        materialApplicationToDoItems.put("materialApplicationToDoItems", overseaReportMapper.materialApplicationToDoItems(userId));
        toDoTaskList.add(materialApplicationToDoItems);

        Map<String, Object> materialApplicationWithoutMaterialNo = new HashMap<>();
        materialApplicationWithoutMaterialNo.put("materialApplicationWithoutMaterialNo", overseaReportMapper.materialApplicationWithoutMaterialNo(userId));
        toDoTaskList.add(materialApplicationWithoutMaterialNo);

        Map<String, Object> overseaRequisitionToDoItems = new HashMap<>();
        overseaRequisitionToDoItems.put("overseaRequisitionToDoItems", overseaReportMapper.overseaRequisitionToDoItems(userId));
        toDoTaskList.add(overseaRequisitionToDoItems);

        Map<String, Object> overseaRequisitionWithoutOut = new HashMap<>();
        overseaRequisitionWithoutOut.put("overseaRequisitionWithoutOut", overseaReportMapper.overseaRequisitionWithoutOut(userId));
        toDoTaskList.add(overseaRequisitionWithoutOut);

        Map<String, Object> orderWorkshopQuantityEachStatus = new HashMap<>();
        orderWorkshopQuantityEachStatus.put("orderWorkshopQuantityEachStatus", overseaReportMapper.orderWorkshopQuantityEachStatus(userId));
        toDoTaskList.add(orderWorkshopQuantityEachStatus);

        return toDoTaskList;
    }

    /** 海外仓首页，车间请购单整单追溯查询 */
    @Override
    public ResponseResult getOrderWorkshopTrace(WelcomePageSearchDTO welcomePageSearchDTO, String userId) {
        if (StringUtils.isNotEmpty(welcomePageSearchDTO.getUserId())){
            userId = welcomePageSearchDTO.getUserId();
        }
        IPage iPage = welcomePageSearchDTO.getPage();
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<Map<String, Object>> mapList = overseaReportMapper.orderWorkshopTrace(iPage, welcomePageSearchDTO, userId);
        if (mapList != null && mapList.size() > 0){
            for (int i = 0; i < mapList.size(); i ++){
                Map<String, Object> map = mapList.get(i);
                String spmsId = map.get("spmsId") == null ? "" : map.get("spmsId").toString();
                if (StringUtils.isNotEmpty(spmsId)){
                    JSONObject dataToSrm = formatDataSend(spmsId);
                    JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSrm));
                    JSONObject returnDate = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
                    //按工厂请购单号查询 SRM 状态
                    //"1"——待采购处理
                    //"2"——已下单未交付
                    //"3"——国内全部收货
                    if ("S".equals(returnDate.getString("TYPE"))){
                        String requestType = returnDate.getJSONArray("DATA").getJSONObject(0).getString("requestType");
                        if ("1".equals(requestType)){
                            map.put("srmStatus", "9");
                        }
                        if ("2".equals(requestType)){
                            map.put("srmStatus", "10");
                        }
                        if ("3".equals(requestType)){
                            map.put("srmStatus", "11");
                        }
                    } else {
                        map.put("srmStatus", "");
                    }
                } else {
                    map.put("srmStatus", "");
                }
                resultList.add(map);
            }
        }
        return ResponseResult.success().add("orderWorkshopTraceList", iPage.setRecords(resultList));
    }

    /** 海外仓首页，工厂请购单整单追溯查询 */
    @Override
    public ResponseResult getOrderWerksTrace(WelcomePageWerksOrderDTO welcomePageWerksOrderDTO, String userId) {
        IPage iPage = welcomePageWerksOrderDTO.getPage();
        List<Map<String, Object>> resultList = new ArrayList<>();
        List<Map<String, Object>> mapList = overseaReportMapper.orderWerksTrace(iPage, welcomePageWerksOrderDTO);
        if (mapList != null && mapList.size() > 0){
            for (int i = 0; i < mapList.size(); i ++){
                Map<String, Object> map = mapList.get(i);
                String spmsId = map.get("spmsId") == null ? "" : map.get("spmsId").toString();
                if (StringUtils.isNotEmpty(spmsId)){
                    JSONObject dataToSrm = formatDataSend(spmsId);
                    JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSrm));
                    JSONObject returnDate = message.getJSONObject("RESPONSE").getJSONObject("RETURN_DATA");
                    //按工厂请购单号查询 SRM 状态
                    //"1"——待采购处理
                    //"2"——已下单未交付
                    //"3"——国内全部收货
                    if ("S".equals(returnDate.getString("TYPE"))){
                        String requestType = returnDate.getJSONArray("DATA").getJSONObject(0).getString("requestType");
                        if ("1".equals(requestType)){
                            map.put("srmStatus", "9");
                        }
                        if ("2".equals(requestType)){
                            map.put("srmStatus", "10");
                        }
                        if ("3".equals(requestType)){
                            map.put("srmStatus", "11");
                        }
                    } else {
                        map.put("srmStatus", "");
                    }
                }
                resultList.add(map);
            }
        }
        return ResponseResult.success().add("orderWerksTraceList", iPage.setRecords(resultList));
    }

    /** 按工厂请购单uuid查询所有关联箱码所在位置 */
    @Override
    public ResponseResult getOrderWerksBoxTrace(String uuid) {
        try {
            if (StringUtils.isEmpty(uuid)){
                return ResponseResult.error("请求参数错误请重试");
            }
            List<Map<String, Object>> orderWerksDtlTraceList = overseaReportMapper.orderWerksBoxTraceListByUuid(uuid);
            // 以下注释部分为追溯方式：先按工厂请购单 uuid 获取工厂请购单明细行；再根据每一行明细行的 uuid + 行号，查询关联箱码及所有箱码当前位置；
            //List<Map<String, Object>> orderWerksDtlTraceList = new ArrayList<>();
            //List<Map<String, Object>> orderWerksDtlList = overseaReportMapper.orderWerksDtlList(uuid);
            //if (orderWerksDtlList != null && orderWerksDtlList.size() > 0){
            //    for (int i = 0; i < orderWerksDtlList.size(); i ++){
            //        Map<String, Object> orderWerksDtl = orderWerksDtlList.get(i);
            //        String orderWerksUuid = orderWerksDtl.get("orderWerksUuid") == null ? "" : orderWerksDtl.get("orderWerksUuid").toString();
            //        String rowIdWerks = orderWerksDtl.get("rowIdWerks") == null ? "" : orderWerksDtl.get("rowIdWerks").toString();
            //        if (StringUtils.isNotEmpty(orderWerksUuid) && StringUtils.isNotEmpty(rowIdWerks)){
            //            List<Map<String, Object>> boxLog = overseaReportMapper.orderWerksBoxTraceList(orderWerksUuid, rowIdWerks);
            //            orderWerksDtl.put("boxTraceList", boxLog);
            //        } else {
            //            orderWerksDtl.put("boxTraceList", new ArrayList<>());
            //        }
            //        orderWerksDtlTraceList.add(orderWerksDtl);
            //    }
            //}
            return ResponseResult.success().add("orderWerksDtlTraceList", orderWerksDtlTraceList);
        } catch (Exception e){
            e.printStackTrace();
            return ResponseResult.error("请求数据失败").add("error", e.getMessage());
        }
    }


    /** 根据工厂请购单单号，向SRM请求SRM系统整单状态 */
    @Override
    public ResponseResult getOrderStatusFromSrm(String spmsId) {
        JSONObject dataToSap = formatDataSend(spmsId);
        JSONObject message = JSONObject.parseObject(iFeignServiceCommon.sendRestToSapCommon(dataToSap));
        return ResponseResult.success().add("dataToSap", dataToSap).add("sapReturnedMessage", message);
    }

    public JSONObject formatDataSend(String spmsId){
        JSONObject doc = new JSONObject();
        JSONObject REQUEST = new JSONObject();
        JSONObject ESB_ATTRS = new JSONObject();
        JSONObject REQUEST_DATA = new JSONObject();

        ESB_ATTRS.put("App_ID", "SPMS");
        ESB_ATTRS.put("Application_ID", "00020000000002");
        ESB_ATTRS.put("Transaction_ID", UUID.randomUUID().toString());

        JSONObject item = new JSONObject();
        item.put("purchaseRequestNumber", spmsId);

        JSONArray Items = new JSONArray();
        Items.add(item);

        REQUEST_DATA.put("Items", Items);
        REQUEST_DATA.put("Operation", "spms_srm_purchase_request_head_type");
        REQUEST_DATA.put("Type", "purchase_request_head_type");

        REQUEST.put("ESB_ATTRS", ESB_ATTRS);
        REQUEST.put("REQUEST_DATA", REQUEST_DATA);

        doc.put("REQUEST", REQUEST);
        return doc;
    }


    /**
     根据工厂、工厂请购单号、日期区间，查询符合条件下所有请购单全生命周期关键节点日期数据
     werks 必输；
     */
    @Override
    public ResponseResult getOrderKeyDates(OverseaReport overseaReport, String userId) {
        if (overseaReport == null || StringUtils.isEmpty(overseaReport.getWerks())){
            return ResponseResult.error("请求工厂不能为空");
        }
        return ResponseResult.success().add("orderKeyDatesList", overseaReportMapper.getOrderKeyDates(overseaReport));
    }
}


